using System.Collections.Generic;
using System.Linq;

namespace DeclarativeTest.Core.Support
{
	/// <summary>
	/// <see cref="IActionFactory"/> that decorates <see cref="IActionFactory"/> collection.
	/// </summary>
	public class CompositeActionFactory : IActionFactory
	{
		#region Private fields

		readonly List<IActionFactory> _factories = new List<IActionFactory>();

		#endregion

		#region Implementation of IActionFactory

		/// <summary>
		/// Determines whether the factory can create action.
		/// </summary>
		/// <param name="actionInfo">ActionInfo</param>
		/// <returns>true is factory can create action</returns>
		public bool CanCreateAction( ActionInfo actionInfo )
		{
			return _factories.Any( factory => factory.CanCreateAction( actionInfo ) );
		}

		/// <summary>
		/// Creates action by <see cref="ActionInfo"/>
		/// </summary>
		/// <param name="testCase">Parent <see cref="ITestCase"/></param>
		/// <param name="actionInfo">ActionInfo</param>
		/// <returns>An instance of <see cref="IAction"/></returns>
		public IAction CreateAction( IDataProvider testCase, ActionInfo actionInfo )
		{
			IActionFactory actionFactory = _factories.First( factory => factory.CanCreateAction( actionInfo ) );
			return actionFactory.CreateAction( testCase, actionInfo );
		}

		#endregion

		/// <summary>
		/// Adds factory to internal list
		/// </summary>
		/// <param name="factory">factory</param>
		public void AddFactory( IActionFactory factory )
		{
			Assume.ArgumentIsNotNull( factory, "factory" );

			_factories.Add( factory );
		}
	}
}